package net.georel.representation.categorisation.main;

import java.io.IOException;
import java.util.Arrays;

import net.georel.representation.categorisation.analysis.Analyse_Classification;
import net.georel.representation.categorisation.analysis.ProportionalClassifier;
import net.georel.representation.categorisation.analysis.R_Classifications;
import net.georel.representation.categorisation.datasource.CreateClassifiedFeatureCollection;
import net.georel.representation.categorisation.datasource.CreateShapefile;
import net.georel.representation.categorisation.datasource.WebFeatureService;

import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureCollections;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.SchemaException;
import org.geotools.filter.text.cql2.CQL;
import org.geotools.filter.text.cql2.CQLException;
import org.geotools.ows.ServiceException;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;
import org.opengis.referencing.FactoryException;



public class main_initial {
private static FeatureCollection inputFC = FeatureCollections.newCollection();
private static int numClasses=6;
private static String stRelevanceFieldName ="rel_cpl_pgr";
private static String stSpaceTimeFieldName ="s_spatiotem";
private static String stDirectionFieldName ="s_direction";
private static String stClusterFieldName ="s_cluster";
private static String stTopicalFieldName ="s_topicalit";
private static String stCoLocationFieldName ="s_colocatio";
	/**
	 * @param args
	 * @throws SchemaException 
	 * @throws FactoryException 
	 * @throws IOException 
	 * @throws ServiceException 
	 * @throws CQLException 
	 */
	public static void main(String[] args) throws ServiceException, IOException, FactoryException, SchemaException, CQLException {
		//take different number of atts, if two differ then must use a compensatory
		System.out.println("loading data.....");
		inputFC = WebFeatureService.getWFSdata("schroeder:pec_a07");
		Filter filter = CQL.toFilter(stRelevanceFieldName+" > 0");
		inputFC = inputFC.subCollection(filter);
		
		double[] relevanceValues = getRelevanceArray();
		double[] relevanceClusterValues = getClusterRelevanceArray();
		double[] relevanceCoLocValues = getCoLocationRelevanceArray();
		double[] relevanceTopicalValues = getTopicalRelevanceArray();
		double[] relevanceSTValues = getSTRelevanceArray();
		double[] relevanceDirectionValues = getDirectionRelevanceArray();
		System.out.println("sorting data.....");
		//Arrays.sort(relevanceValues);
		System.out.println("classifiying data.....");
		
		int[] kmeansRelevanceClassification = R_Classifications.getKMeansClassification(relevanceValues, numClasses);
		int[] kmeansClusterClassification = R_Classifications.getKMeansClassification(relevanceClusterValues, numClasses);
		int[] kmeansCoLocClassification = R_Classifications.getKMeansClassification(relevanceCoLocValues, numClasses);
		int[] kmeansTopicalClassification = R_Classifications.getKMeansClassification(relevanceTopicalValues, numClasses);
		int[] kmeansSTClassification = R_Classifications.getKMeansClassification(relevanceSTValues, numClasses);
		int[] kmeansDirectionClassification = R_Classifications.getKMeansClassification(relevanceDirectionValues, numClasses);
		
		int[] jenksRelevanceClassification = R_Classifications.getJenksClassification(relevanceValues, numClasses);
		int[] jenksClusterClassification = R_Classifications.getJenksClassification(relevanceClusterValues, numClasses);
		int[] jenksCoLocClassification = R_Classifications.getJenksClassification(relevanceCoLocValues, numClasses);
		int[] jenksTopicalClassification = R_Classifications.getJenksClassification(relevanceTopicalValues, numClasses);
		int[] jenksSTClassification = R_Classifications.getJenksClassification(relevanceSTValues, numClasses);
		int[] jenksDirectionClassification = R_Classifications.getJenksClassification(relevanceDirectionValues, numClasses);
		
		int[] fisherRelevanceClassification = R_Classifications.getFisherClassification(relevanceValues, numClasses);
		int[] fisherClusterClassification = R_Classifications.getFisherClassification(relevanceClusterValues, numClasses);
		int[] fisherCoLocClassification = R_Classifications.getFisherClassification(relevanceCoLocValues, numClasses);
		int[] fisherTopicalClassification = R_Classifications.getFisherClassification(relevanceTopicalValues, numClasses);
		int[] fisherSTClassification = R_Classifications.getFisherClassification(relevanceSTValues, numClasses);
		int[] fisherDirectionClassification = R_Classifications.getFisherClassification(relevanceDirectionValues, numClasses);
		
		int[] baggedRelevanceClassification = R_Classifications.getBaggedClusterClassification(relevanceValues, numClasses);
		int[] baggedClusterClassification = R_Classifications.getBaggedClusterClassification(relevanceClusterValues, numClasses);
		int[] baggedCoLocClassification = R_Classifications.getBaggedClusterClassification(relevanceCoLocValues, numClasses);
		int[] baggedTopicalClassification = R_Classifications.getBaggedClusterClassification(relevanceTopicalValues, numClasses);
		int[] baggedSTClassification = R_Classifications.getBaggedClusterClassification(relevanceSTValues, numClasses);
		int[] baggedDirectionClassification = R_Classifications.getBaggedClusterClassification(relevanceDirectionValues, numClasses);
		
		int[] hierarchicalRelevanceClassification = R_Classifications.getHierarchicalClusterClassification(relevanceValues, numClasses);
		int[] hierarchicalClusterClassification = R_Classifications.getHierarchicalClusterClassification(relevanceClusterValues, numClasses);
		int[] hierarchicalCoLocClassification = R_Classifications.getHierarchicalClusterClassification(relevanceCoLocValues, numClasses);
		int[] hierarchicalTopicalClassification = R_Classifications.getHierarchicalClusterClassification(relevanceTopicalValues, numClasses);
		int[] hierarchicalSTClassification = R_Classifications.getHierarchicalClusterClassification(relevanceSTValues, numClasses);
		int[] hierarchicalDirectionClassification = R_Classifications.getHierarchicalClusterClassification(relevanceDirectionValues, numClasses);
				
		//int[] proportionalClassification = ProportionalClassifier.getProportionalClassification(relevanceValues, numClasses, 2);*/
		
		System.out.println("creating shapefile data.....");
		
		String[] columnNames = new String[30];
		columnNames[0]="kgeorel";columnNames[1]="kcluster";columnNames[2]="kcolocat";
		columnNames[3]="ktopical";columnNames[4]="kspacetime";columnNames[5]="kdirection";
		
		columnNames[6]="jgeorel";columnNames[7]="jcluster";columnNames[8]="jcolocat";
		columnNames[9]="jtopical";columnNames[10]="jspacetime";columnNames[11]="jdirection";
		
		columnNames[12]="fgeorel";columnNames[13]="fcluster";columnNames[14]="fcolocat";
		columnNames[15]="ftopical";columnNames[16]="fspacetime";columnNames[17]="fdirection";
		
		columnNames[18]="bgeorel";columnNames[19]="bcluster";columnNames[20]="bcolocat";
		columnNames[21]="btopical";columnNames[22]="bspacetime";columnNames[23]="bdirection";
		
		columnNames[24]="hgeorel";columnNames[25]="hcluster";columnNames[26]="hcolocat";
		columnNames[27]="htopical";columnNames[28]="hspacetime";columnNames[29]="hdirection";
		
		CreateClassifiedFeatureCollection cCFC = new CreateClassifiedFeatureCollection();
		cCFC.initialiseArrayConcatenation(kmeansClusterClassification.length, 30);
		
		cCFC.addArray(kmeansRelevanceClassification);
		cCFC.addArray(kmeansClusterClassification);
		cCFC.addArray(kmeansCoLocClassification);
		cCFC.addArray(kmeansTopicalClassification);
		cCFC.addArray(kmeansSTClassification);
		cCFC.addArray(kmeansDirectionClassification);
		
		cCFC.addArray(jenksRelevanceClassification);
		cCFC.addArray(jenksClusterClassification);
		cCFC.addArray(jenksCoLocClassification);
		cCFC.addArray(jenksTopicalClassification);
		cCFC.addArray(jenksSTClassification);
		cCFC.addArray(jenksDirectionClassification);
		
		cCFC.addArray(fisherRelevanceClassification);
		cCFC.addArray(fisherClusterClassification);
		cCFC.addArray(fisherCoLocClassification);
		cCFC.addArray(fisherTopicalClassification);
		cCFC.addArray(fisherSTClassification);
		cCFC.addArray(fisherDirectionClassification);
		
		cCFC.addArray(baggedRelevanceClassification);
		cCFC.addArray(baggedClusterClassification);
		cCFC.addArray(baggedCoLocClassification);
		cCFC.addArray(baggedTopicalClassification);
		cCFC.addArray(baggedSTClassification);
		cCFC.addArray(baggedDirectionClassification);
		
		cCFC.addArray(hierarchicalRelevanceClassification);
		cCFC.addArray(hierarchicalClusterClassification);
		cCFC.addArray(hierarchicalCoLocClassification);
		cCFC.addArray(hierarchicalTopicalClassification);
		cCFC.addArray(hierarchicalSTClassification);
		cCFC.addArray(hierarchicalDirectionClassification);
		
		cCFC.addInputFeatureCollection(inputFC);
		cCFC.setColumnNames(columnNames);
		cCFC.buildOutputFeatureCollection();
		CreateShapefile.writetoShape(cCFC.getOutputFeatureCollection(), cCFC.getOutputFeatureCollection().getSchema().getCoordinateReferenceSystem());
		System.out.println(cCFC.getOutputFeatureCollection().size());
		
		/*System.out.println("kmeans");
		Analyse_Classification.getMemberCountInEachClass(kmeansClassification, numClasses);
		System.out.println();
		System.out.println("quantile");
		Analyse_Classification.getMemberCountInEachClass(quantileClassification, numClasses);
		System.out.println();
		System.out.println("jenks");
		Analyse_Classification.getMemberCountInEachClass(JenksClassification, numClasses);
		System.out.println();
		System.out.println("SD");
		Analyse_Classification.getMemberCountInEachClass(SDClassification, numClasses);
		System.out.println();
		System.out.println("fisher");
		Analyse_Classification.getMemberCountInEachClass(fisherClassification, numClasses);
		System.out.println();
		System.out.println("bagged");
		Analyse_Classification.getMemberCountInEachClass(baggedClassification, numClasses);
		System.out.println();
		System.out.println("hierarchical");
		Analyse_Classification.getMemberCountInEachClass(hierarchicalClassification, numClasses);
		System.out.println();
		System.out.println("proportional");
		Analyse_Classification.getMemberCountInEachClass(proportionalClassification, numClasses);
		System.out.println("finished classifiying data");*/
	}
	
	private static double[] getRelevanceArray(){
		
		double[] relevanceValues = new double[inputFC.size()];
		
		FeatureIterator iF = inputFC.features();
		int i = 0;
		while(iF.hasNext()){
			SimpleFeature feature = (SimpleFeature) iF.next();			
			relevanceValues[i] = (Double) feature.getAttribute(stRelevanceFieldName);
			i++;
		}
		iF.close();
		return relevanceValues;
		
	}
	
private static double[] getSTRelevanceArray(){
		
		double[] relevanceValues = new double[inputFC.size()];
		
		FeatureIterator iF = inputFC.features();
		int i = 0;
		while(iF.hasNext()){
			SimpleFeature feature = (SimpleFeature) iF.next();			
			relevanceValues[i] = (Double) feature.getAttribute(stSpaceTimeFieldName);
			i++;
		}
		iF.close();
		return relevanceValues;
		
	}

private static double[] getDirectionRelevanceArray(){
	
	double[] relevanceValues = new double[inputFC.size()];
	
	FeatureIterator iF = inputFC.features();
	int i = 0;
	while(iF.hasNext()){
		SimpleFeature feature = (SimpleFeature) iF.next();			
		relevanceValues[i] = (Double) feature.getAttribute(stDirectionFieldName);
		i++;
	}
	iF.close();
	return relevanceValues;
	
}

private static double[] getTopicalRelevanceArray(){
	
	double[] relevanceValues = new double[inputFC.size()];
	
	FeatureIterator iF = inputFC.features();
	int i = 0;
	while(iF.hasNext()){
		SimpleFeature feature = (SimpleFeature) iF.next();			
		relevanceValues[i] = (Double) feature.getAttribute(stTopicalFieldName);
		i++;
	}
	iF.close();
	return relevanceValues;
	
}

private static double[] getCoLocationRelevanceArray(){
	
	double[] relevanceValues = new double[inputFC.size()];
	
	FeatureIterator iF = inputFC.features();
	int i = 0;
	while(iF.hasNext()){
		SimpleFeature feature = (SimpleFeature) iF.next();			
		relevanceValues[i] = (Double) feature.getAttribute(stCoLocationFieldName);
		i++;
	}
	iF.close();
	return relevanceValues;
	
}

private static double[] getClusterRelevanceArray(){
	
	double[] relevanceValues = new double[inputFC.size()];
	
	FeatureIterator iF = inputFC.features();
	int i = 0;
	while(iF.hasNext()){
		SimpleFeature feature = (SimpleFeature) iF.next();			
		relevanceValues[i] = (Double) feature.getAttribute(stClusterFieldName);
		i++;
	}
	iF.close();
	return relevanceValues;
	
}
	
	
}
